{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Abstractive"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"alert alert-info\">\n",
    "\n",
    "This tutorial is available as an IPython notebook at [Malaya/example/augmentation-abstractive](https://github.com/huseinzol05/Malaya/tree/master/example/augmentation-abstractive).\n",
    "    \n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"alert alert-warning\">\n",
    "\n",
    "Results generated using stochastic methods.\n",
    "    \n",
    "</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "\n",
    "os.environ['CUDA_VISIBLE_DEVICES'] = ''\n",
    "os.environ['TF_FORCE_GPU_ALLOW_GROWTH'] = 'true'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/husein/.local/lib/python3.8/site-packages/bitsandbytes/cextension.py:34: UserWarning: The installed version of bitsandbytes was compiled without GPU support. 8-bit optimizers, 8-bit multiplication, and GPU quantization are unavailable.\n",
      "  warn(\"The installed version of bitsandbytes was compiled without GPU support. \"\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "/home/husein/.local/lib/python3.8/site-packages/bitsandbytes/libbitsandbytes_cpu.so: undefined symbol: cadam32bit_grad_fp32\n",
      "CPU times: user 2.9 s, sys: 3.74 s, total: 6.64 s\n",
      "Wall time: 2.24 s\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/husein/dev/malaya/malaya/tokenizer.py:214: FutureWarning: Possible nested set at position 3397\n",
      "  self.tok = re.compile(r'({})'.format('|'.join(pipeline)))\n",
      "/home/husein/dev/malaya/malaya/tokenizer.py:214: FutureWarning: Possible nested set at position 3927\n",
      "  self.tok = re.compile(r'({})'.format('|'.join(pipeline)))\n"
     ]
    }
   ],
   "source": [
    "%%time\n",
    "\n",
    "import malaya"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Why augmentation\n",
    "\n",
    "Let say you have a very limited labelled corpus, and you want to add more, but labelling is very costly.\n",
    "\n",
    "So, text augmentation! We provided few augmentation interfaces in Malaya."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### List available HuggingFace models"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'mesolitica/translation-t5-tiny-standard-bahasa-cased': {'Size (MB)': 139,\n",
       "  'Suggested length': 1536,\n",
       "  'ms-pasar ms chrF2++': 49.01,\n",
       "  'en-pasar ms chrF2++': 45.29,\n",
       "  'ms-manglish chrF2++': 37.55,\n",
       "  'en-manglish chrF2++': 44.32,\n",
       "  'from lang': ['en', 'ms', 'ind', 'jav', 'bjn'],\n",
       "  'to lang': ['manglish', 'pasar ms']},\n",
       " 'mesolitica/translation-t5-small-standard-bahasa-cased': {'Size (MB)': 242,\n",
       "  'Suggested length': 1536,\n",
       "  'ms-pasar ms chrF2++': 54.3,\n",
       "  'en-pasar ms chrF2++': 51.88,\n",
       "  'ms-manglish chrF2++': 39.98,\n",
       "  'en-manglish chrF2++': 44.58,\n",
       "  'from lang': ['en', 'ms', 'ind', 'jav', 'bjn'],\n",
       "  'to lang': ['manglish', 'pasar ms']},\n",
       " 'mesolitica/translation-t5-base-standard-bahasa-cased': {'Size (MB)': 892,\n",
       "  'Suggested length': 1536,\n",
       "  'ms-pasar ms chrF2++': 50.25,\n",
       "  'en-pasar ms chrF2++': 49.26,\n",
       "  'ms-manglish chrF2++': 38.41,\n",
       "  'en-manglish chrF2++': 43.38,\n",
       "  'from lang': ['en', 'ms', 'ind', 'jav', 'bjn'],\n",
       "  'to lang': ['manglish', 'pasar ms']},\n",
       " 'mesolitica/translation-nanot5-tiny-malaysian-cased': {'Size (MB)': 205,\n",
       "  'Suggested length': 2048,\n",
       "  'ms-pasar ms chrF2++': 53.36,\n",
       "  'en-pasar ms chrF2++': 49.31,\n",
       "  'ms-manglish chrF2++': 37.22,\n",
       "  'en-manglish chrF2++': 43.5,\n",
       "  'from lang': ['en',\n",
       "   'ms',\n",
       "   'ind',\n",
       "   'jav',\n",
       "   'bjn',\n",
       "   'manglish',\n",
       "   'pasar ms',\n",
       "   'mandarin',\n",
       "   'pasar mandarin'],\n",
       "  'to lang': ['manglish', 'pasar ms', 'pasar mandarin']},\n",
       " 'mesolitica/translation-nanot5-small-malaysian-cased': {'Size (MB)': 358,\n",
       "  'Suggested length': 2048,\n",
       "  'ms-pasar ms chrF2++': 55.09,\n",
       "  'en-pasar ms chrF2++': 53.01,\n",
       "  'ms-manglish chrF2++': 40.19,\n",
       "  'en-manglish chrF2++': 45.69,\n",
       "  'from lang': ['en',\n",
       "   'ms',\n",
       "   'ind',\n",
       "   'jav',\n",
       "   'bjn',\n",
       "   'manglish',\n",
       "   'pasar ms',\n",
       "   'mandarin',\n",
       "   'pasar mandarin'],\n",
       "  'to lang': ['manglish', 'pasar ms', 'pasar mandarin']},\n",
       " 'mesolitica/translation-nanot5-base-malaysian-cased': {'Size (MB)': 990,\n",
       "  'Suggested length': 2048,\n",
       "  'ms-pasar ms chrF2++': 55.57,\n",
       "  'en-pasar ms chrF2++': 55.02,\n",
       "  'ms-manglish chrF2++': 40.17,\n",
       "  'en-manglish chrF2++': 43.44,\n",
       "  'from lang': ['en',\n",
       "   'ms',\n",
       "   'ind',\n",
       "   'jav',\n",
       "   'bjn',\n",
       "   'manglish',\n",
       "   'pasar ms',\n",
       "   'mandarin',\n",
       "   'pasar mandarin'],\n",
       "  'to lang': ['manglish', 'pasar ms', 'pasar mandarin']}}"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "malaya.augmentation.abstractive.available_huggingface"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Load HuggingFace model\n",
    "\n",
    "```python\n",
    "def huggingface(\n",
    "    model: str = 'mesolitica/translation-t5-small-standard-bahasa-cased',\n",
    "    force_check: bool = True,\n",
    "    **kwargs,\n",
    "):\n",
    "    \"\"\"\n",
    "    Load HuggingFace model to abstractive text augmentation.\n",
    "\n",
    "    Parameters\n",
    "    ----------\n",
    "    model: str, optional (default='mesolitica/translation-t5-small-standard-bahasa-cased')\n",
    "        Check available models at `malaya.augmentation.abstractive.available_huggingface`.\n",
    "    force_check: bool, optional (default=True)\n",
    "        Force check model one of malaya model.\n",
    "        Set to False if you have your own huggingface model.\n",
    "\n",
    "    Returns\n",
    "    -------\n",
    "    result: malaya.torch_model.huggingface.Translation\n",
    "    \"\"\"\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "model = malaya.augmentation.abstractive.huggingface(model = 'mesolitica/translation-nanot5-small-malaysian-cased')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Generate\n",
    "\n",
    "```python\n",
    "def generate(self, strings: List[str], to_lang: str = 'ms', **kwargs):\n",
    "    \"\"\"\n",
    "    Generate texts from the input.\n",
    "\n",
    "    Parameters\n",
    "    ----------\n",
    "    strings : List[str]\n",
    "    to_lang: str, optional (default='ms')\n",
    "        target language to translate.\n",
    "    **kwargs: vector arguments pass to huggingface `generate` method.\n",
    "        Read more at https://huggingface.co/docs/transformers/main_classes/text_generation\n",
    "\n",
    "        If you are using `use_ctranslate2`, vector arguments pass to ctranslate2 `translate_batch` method.\n",
    "        Read more at https://opennmt.net/CTranslate2/python/ctranslate2.Translator.html?highlight=translate_batch#ctranslate2.Translator.translate_batch\n",
    "\n",
    "    Returns\n",
    "    -------\n",
    "    result: List[str]\n",
    "    \"\"\"\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "string = 'saya suka makan ayam dan ikan'\n",
    "string2 = 'saya sebenarnya tak suka sangat dekat lelaki tu, ketiak masam sebab tak mandi'\n",
    "string3 = 'Perdana Menteri berkata, beliau perlu memperoleh maklumat terperinci berhubung isu berkenaan sebelum kerajaan dapat mengambil sebarang tindakan lanjut. Bagaimanapun, beliau yakin masalah itu dapat diselesaikan dan pentadbiran kerajaan boleh berfungsi dengan baik.'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "spaces_between_special_tokens is deprecated and will be removed in transformers v5. It was adding spaces between `added_tokens`, not special tokens, and does not exist in our fast implementation. Future tokenizers will handle the decoding process on a per-model rule.\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "['aku suka makan ayam dan ikan',\n",
       " 'aku sebenarnya tak suka sangat dekat laki tu, ketiak masam sebab tak mandi',\n",
       " 'Perdana Menteri berkata, beliau perlu mendapatkan maklumat terperinci berhubung isu berkenaan sebelum kerajaan dapat mengambil sebarang tindakan lanjut.  Bagaimanapun, beliau yakin masalah itu dapat diselesaikan dan pentadbiran kerajaan dapat berfungsi dengan baik.']"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.generate([string, string2, string3], to_lang = 'pasar ms', max_length = 256)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Good thing about HuggingFace\n",
    "\n",
    "In `generate` method, you can do greedy, beam, sampling, nucleus decoder and so much more, read it at https://huggingface.co/blog/how-to-generate"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['rakyat mmg tak suke u pun',\n",
       " 'rakyat mmg tak suke awak pun',\n",
       " 'rakyat memang tak suka awak pun',\n",
       " 'rakyat mmg tak suka awak pun',\n",
       " 'rakyat memang tak suka awak pun']"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "outputs = model.generate(['rakyat memang tak suka awak pun'], to_lang = 'pasar ms',\n",
    "                         max_length = 100, do_sample=True, top_k=100, top_p=0.95, temperature=0.7,\n",
    "                         num_return_sequences=5)\n",
    "outputs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['aku suka makan ayam ikan',\n",
       " 'i suka makan ayam ikan',\n",
       " 'suka makan ayam dan ikan',\n",
       " 'aku memang tak suka sangat dekat lelaki tu  ketiak masam sebab tak mandi',\n",
       " 'i paling x suka dekat lelaki tu  ketiak masam sbb x mandi',\n",
       " 'aku sebenarnya tak suka sangat dekat laki tu, ketiak masam sebab tak mandi',\n",
       " '\"Perdana Menteri berkata, beliau perlu mendapatkan maklumat terperinci berhubung isu berkenaan sebelum kerajaan dapat mengambil sebarang tindakan lanjut.  Bagaimanapun, beliau yakin masalah itu dapat diselesaikan dan pentadbiran kerajaan dapat berfungsi dengan baik.\"  \"Terima kasih, Teks itu sudah cukup untuk ditafsirkan,\" tambah Perdana Menteri.',\n",
       " 'Perdana Menteri berkata, beliau perlu mendapatkan maklumat terperinci berhubung isu berkenaan sebelum kerajaan dapat mengambil sebarang tindakan lanjut.  Bagaimanapun, beliau yakin perkara itu dapat diselesaikan dan pentadbiran kerajaan dapat berfungsi dengan baik.  http://www. great.com/arena..  [ Last edited by  yanhong_naz at 31-12-2007 09:12 AM ]',\n",
       " 'Perdana Menteri berkata, beliau perlu mendapatkan maklumat terperinci berhubung isu berkenaan sebelum kerajaan boleh mengambil sebarang tindakan lanjut.  Bagaimanapun, beliau yakin masalah berkenaan dapat diselesaikan dan pentadbiran kerajaan dapat berfungsi dengan baik.']"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "outputs = model.generate([string, string2, string3], to_lang = 'pasar ms',\n",
    "                         max_length = 100, do_sample=True, top_k=100, top_p=0.95, temperature=0.7,\n",
    "                         num_return_sequences=3)\n",
    "outputs"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can choose different generating method and still maintain the same polarity."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "strings = [\n",
    "    'bodoh betul kerajaan ni, mana kebebasan bersuara',\n",
    "    'Perbincangan khas itu juga bertujuan bagi Seri Paduka mendapat pandangan Raja-Raja Melayu untuk membolehkan baginda membuat keputusan yang terbaik demi kepentingan dan kesejahteraan negara serta rakyat',\n",
    "    'semalam saya buka tv tengok berita, katanya ada tanah runtuh',\n",
    "    'i hate him so much, perangai teruk!'\n",
    "]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['bodoh la pakatan harapan ni  mana kebebasan bersuara',\n",
       " 'bodoh betul kerajaan ni,mana kebebasan bersuara',\n",
       " 'bodoh betul kerajaan ni mana kebebasan bersuara',\n",
       " 'Kongres khas itu turut bertujuan untuk Seri Paduka mendapat pandangan Raja-Raja Melayu bagi membolehkan baginda membuat keputusan yang terbaik demi kepentingan dan kesejahteraan negara dan rakyat',\n",
       " 'Perbincangan khas itu juga bertujuan bagi Seri Paduka mendapat pandangan Raja-Raja Melayu bagi membolehkan baginda membuat keputusan yang terbaik demi kepentingan dan kesejahteraan negara serta rakyat',\n",
       " 'Perbincangan khas itu juga bertujuan bagi Seri Paduka mendapat pandangan Raja-Raja Melayu bagi membolehkan baginda membuat keputusan yang terbaik demi kepentingan dan kesejahteraan negara serta rakyat https://t.co/M9BjB7UXpQ',\n",
       " 'semalam aku bukak tv tgk berita katanya tanah runtuh',\n",
       " ' semalam bukak tv tengok berita dia kata tanah runtuh katanya',\n",
       " ' semalam aku buka tv tengok berita katanya tanah runtuh',\n",
       " 'i hate him so much  bad perangai!',\n",
       " 'i hate him so much  perangai hazab!',\n",
       " 'i benci dia macam tu, perangai hampeh!']"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "outputs = model.generate(strings, to_lang = 'pasar ms',\n",
    "                         max_length = 100, do_sample=True, top_k=100, top_p=0.95, temperature=0.8,\n",
    "                         num_return_sequences=3)\n",
    "outputs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['bodoh betul kerajaan ni mana kebebasan bersuara',\n",
       " 'bodoh la kerajaan ni, mana bebas bersuara',\n",
       " 'bodoh betul gomen ni  mana freedom of speech',\n",
       " 'Perbincangan khas itu juga bertujuan agar Seri Paduka mendapat pandangan Raja-Raja Melayu bagi membolehkan baginda membuat keputusan yang terbaik demi kepentingan dan kesejahteraan negara serta rakyat https://t.co/z6R9XVdZdD',\n",
       " 'Perbincangan khas itu juga bertujuan untuk Seri Paduka mendapat pandangan Raja-Raja Melayu untuk membolehkan baginda membuat keputusan yang terbaik demi kepentingan dan kesejahteraan negara serta rakyat',\n",
       " 'Perbincangan khas itu juga bertujuan bagi Seri Paduka mendapat pandangan Raja-Raja Melayu untuk membolehkan baginda membuat keputusan yang terbaik demi kepentingan dan kesejahteraan negara serta rakyat',\n",
       " 'semalam aku buka tv tengok berita, kata ada tanah runtuh katanya',\n",
       " ' semalam saya buka tb tengok berita, katanya ada tanah runtuh',\n",
       " 'semalam aku bukak tv tengok berita, ada tanah runtuh katanya ',\n",
       " 'i hate him so much  perangai teruk!',\n",
       " 'i benci dia ni, perangai teruk!',\n",
       " 'i hate him so much  perangai teruk!']"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "outputs = model.generate(strings, to_lang = 'pasar ms',\n",
    "                         max_length = 100, do_sample=True, penalty_alpha=0.9, top_k=4, temperature=0.9,\n",
    "                         num_return_sequences=3)\n",
    "outputs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
